package com.deere.manufacture.service;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.deere.dao.GenericDao;
import com.deere.model.GenericPart;
import com.deere.model.ItemWorkflow;
import com.deere.model.ProductionOrderItem;
import com.deere.model.Scrap;
import com.deere.model.WorkOrder;
import com.deere.model.enums.WorkOrderStatus;
import com.deere.workprocedure.service.ItemWorkflowService;
import com.deere.workprocedure.service.WorkingProcedureService;

/**
 * 
 * 排产单Service
 */
@Service
public class WorkOrderService {
	
	@Autowired
	private GenericDao<WorkOrder> workOrderDao;
	
	@Autowired
	private WorkingProcedureService wpService;
	
	@Autowired
	private ItemWorkflowService iwService;
	
	@Autowired
	private ProductionService poiService;
	
	@Autowired
	private GenericDao<Scrap> scrapDao;
	
	@Autowired
	private MRPService mrpService;
	
	private static final DateFormat df = new SimpleDateFormat("yyyyMMddHHmmssS");
	/**
	 * 查询出所有的生产计划工作单
	 * @return
	 */
	public List listProductionPlan(){
		return null;
	}
	/**
	 * 批量添加流水单（工作单）。
	 * 每个工作单对应一个零件，根据零件的图号可以知道此零件的加工流程及流程所对应的工序，
	 * 每当创建一个加工计划，则会预先生成此计划对应的工作单。
	 * @param workOrders
	 * @return
	 */
	public void insertWorkOrder(List<WorkOrder> workOrders){
		for(WorkOrder workOrder :workOrders){
			//根据partcode检索出工序
			List<ItemWorkflow> wfs = iwService.getItemWorkflows(workOrder.getPartCode());
			String batchNum = getBatchNum();
			if(null != wfs && wfs.size() > 0)
				for(int i = 0;i < wfs.size();i++){
					ItemWorkflow wf = wfs.get(i);
					if(i ==0){
						workOrder.setStatus(WorkOrderStatus.ACTIVE.toString());
					}else{
						workOrder.setStatus(WorkOrderStatus.NEW.toString());
					}
					workOrder.setBatchNum(batchNum);
					workOrder.setProcedure(wf.getProcedure());
					workOrder.setWpCode(wf.getProcedure().getWpCode());
					workOrder.setSequence(wf.getSequence());
					this.insertWorkOrder(workOrder);
				}
		}
	}
	/**
	 * 获取批次号
	 * @return
	 */
	protected String getBatchNum(){
		return df.format(new java.util.Date());
	}
	/**
	 * 添加流水单（工作单）
	 * @param workOrder
	 * @return
	 */
	public void insertWorkOrder(WorkOrder workOrder){
		if(null == workOrder.getStatus())
			workOrder.setStatus(WorkOrderStatus.NEW.toString());
		workOrderDao.merge(workOrder);
	}

	/**
	 * 报废处理。
	 * 
	 * 首先向报废表中添加一条记录，同时把对应的生产工单中的数量减1。
	 * 报废之后，如果此生产工单的加工数量变成0,则状态置为SCRAP
	 * 
	 * @param workOrder
	 */
	public void scrap(WorkOrder workOrder){
		Scrap scrap = new Scrap();
		scrap.setMoId(workOrder.getId());
		scrapDao.save(scrap);
		
		//
		WorkOrder scrapWorkOrder = workOrderDao.findById(workOrder.getId());
		List<WorkOrder> workOrders = this.queryWorkOrderByBatchNum(scrapWorkOrder);
		for(WorkOrder wo : workOrders){
			int qty = wo.getQuantity()-1;
			wo.setQuantity(qty);
			if(qty <=0){
				wo.setStatus(WorkOrderStatus.SCRAP.toString());
			}
			workOrderDao.update(wo);
		}
		//TODO 更新在制数量
		//mrpService.updateRequiredQty(workOrder.getPartCode());
	}
	/**
	 * 更新工作单
	 * @param workOrder
	 */
	public WorkOrder updateWorkOrder(WorkOrder workOrder){
		Integer id = workOrder.getId();
		WorkOrder workOrderOri = loadWorkOrder(id);
		/*
		 * 如果是新工作单，则更新首检人，首检时间及工人姓名
		 */
		if(WorkOrderStatus.NEW.toString().equals(workOrder.getStatus()) || WorkOrderStatus.ASSIGNED.toString().equals(workOrder.getStatus())){
			workOrderOri.setFirstInspectionName(workOrder.getFirstInspectionName());
			workOrderOri.setFirstInspectionTime(workOrder.getFirstInspectionTime());
			workOrderOri.setStatus(WorkOrderStatus.FCHECK.toString());
			workOrderOri.setManHours(workOrder.getManHours());
		}
		/*
		 * 如果是完成首检，则更新
		 */
		else if(WorkOrderStatus.FCHECK.toString().equals(workOrder.getStatus())){
			workOrderOri.setStatus(WorkOrderStatus.INSPECTED.toString());
			workOrderOri.setQualifiedQuantity(workOrder.getQualifiedQuantity());
			workOrderOri.setQualityInspector(workOrder.getQualityInspector());
			workOrderOri.setReceivingInspection(workOrder.getReceivingInspection());
			workOrderOri.setReceivingInspectionDate(workOrder.getReceivingInspectionDate());
			/*
			 * 如果此工单为零件加工流程工序的最后一道。
			 * 判断依据：
			 * 如果工单中的sequence等于流程表中的最后一道工序的sequence一致，则认为此工单为最后一个工序
			 */
			//获取工序的最后一道工序
			ItemWorkflow workflow = iwService.getLastItemWorkflow(workOrder.getPartCode());
			ProductionOrderItem orderItem = poiService.getPlannedProductionItem(workOrderOri.getProductionOrderItem().getItemId());
			if(workOrderOri.getSequence() == workflow.getSequence()){
				workOrderOri.setStatus(WorkOrderStatus.REPORTED.toString());
				workOrderOri.setCompleteDate(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new java.util.Date()));
				if(orderItem != null){
					
				}
			}else{
				this.activateNextProcedure(workOrderOri);
			}
		}
		/*
		 * 代表上报操作处理
		 */
		else if(WorkOrderStatus.INSPECTED.toString().equals(workOrder.getStatus())){
			workOrderOri.setStatus(WorkOrderStatus.REPORTED.toString());
			workOrderOri.setCompleteDate(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new java.util.Date()));
			/*
			 * 如果此工单最终被通过，则需要把此次完成的零配件数量更新到与之对应的计划中。
			 * UPDATE ProductionOrderItem.
			 * 
			 */
			ItemWorkflow workflow = iwService.getLastItemWorkflow(workOrder.getPartCode());
			ProductionOrderItem orderItem = poiService.getPlannedProductionItem(workOrderOri.getProductionOrderItem().getItemId());
			if(orderItem != null){
				if(workOrderOri.getSequence() == workflow.getSequence()){
					int finishQty = (null == orderItem.getFinishedQty() ? 0 : orderItem.getFinishedQty());
					finishQty+=workOrderOri.getQualifiedQuantity();
					orderItem.setFinishedQty(finishQty);
					orderItem.setCompleted(true);
				}
				poiService.updateFinishQty(orderItem);
			}
		}
		return workOrderDao.merge(workOrderOri);
	}
	/**
	 * 分配工作单
	 * @param workOrder
	 */
	public WorkOrder assignWorkOrder(WorkOrder workOrder){
		Integer id = workOrder.getId();
		WorkOrder workOrderOri = loadWorkOrder(id);
		workOrderOri.setFirstInspectionName(workOrder.getFirstInspectionName());
		workOrderOri.setFirstInspectionTime(workOrder.getFirstInspectionTime());
		workOrderOri.setStatus(WorkOrderStatus.ASSIGNED.toString());
		workOrderOri.setWorkerName(workOrder.getWorkerName());
		workOrderOri.setManHours(workOrder.getManHours());
		workOrderOri.setQualifiedQuantity(workOrder.getQualifiedQuantity());
		workOrderOri.setQualityInspector(workOrder.getQualityInspector());
		workOrderOri.setCompleteDate(workOrder.getCompleteDate());
		workOrderOri.setReceivingInspection(workOrder.getReceivingInspection());
		workOrderOri.setReceivingInspectionDate(workOrder.getReceivingInspectionDate());
		workOrderOri.setWorkshopLeader(workOrder.getWorkshopLeader());
		
		return workOrderDao.merge(workOrderOri);
	}
	/**
	 * 激活当前工序的下一道工序
	 * @param workOrder
	 * @return
	 */
	protected WorkOrder activateNextProcedure(WorkOrder workOrder){
		WorkOrder nextWorkOrder = loadWorkOrder(workOrder.getId()+1);
		if(null != nextWorkOrder){
			nextWorkOrder.setStatus(WorkOrderStatus.ACTIVE.toString());
			return workOrderDao.merge(nextWorkOrder);
		}
		return null;
	}
	/**
	 * 根据条件检索状态为NEW,FCHECK和ASSIGNED的工作单
	 * @param workOrder
	 * @return
	 */
	public List<WorkOrder> getCanReportWorkOrders(WorkOrder workOrder){
		String sql = "from WorkOrder where (status ='COMPLETED' or status ='INSPECTED') ";//status ='FCHECK' or status ='ASSIGNED' or 
		StringBuffer where = new StringBuffer();
		if(null != workOrder){
			if(null != workOrder.getWorkerName() && !"".equals(workOrder.getWorkerName())){
				where.append(" and workerName = '");
				where.append(workOrder.getWorkerName());
				where.append("'");
			}
			if(workOrder.getId() != 0){
				where.append(" and id = ");
				where.append(workOrder.getId());
			}
		}
		
		if(where.length()>0){
			sql+= where.toString();
		}
		return workOrderDao.query(sql);
	}
	/**
	 * 根据条件检索状态为NEW,FCHECK和ASSIGNED的工作单
	 * @param workOrder
	 * @return
	 */
	public List<WorkOrder> getAllWorkOrder(WorkOrder workOrder){
		String sql = "from WorkOrder where (status ='NEW' or status ='FCHECK' or status ='ASSIGNED') ";
		StringBuffer where = new StringBuffer();
		if(null != workOrder){
			if(null != workOrder.getWorkerName() && !"".equals(workOrder.getWorkerName())){
				where.append(" and workerName = '");
				where.append(workOrder.getWorkerName());
				where.append("'");
			}
			if(workOrder.getId() != 0){
				where.append(" and id = ");
				where.append(workOrder.getId());
			}
		}

		if(where.length()>0){
			sql+= where.toString();
		}
		return workOrderDao.query(sql);
	}
	/**
	 * 根据检索<code>itemId</code>所对应的所有工作单
	 * @param itemId
	 * @return
	 */
	public List<WorkOrder> getPlannedProductionItem(Integer itemId){
		String sql = " from WorkOrder wo where productionOrderItem.itemId = "+itemId+" and (status <> 'STOCKED' and status <> 'REPORTED' and status <> 'INSPECTED' and status <> 'SCRAP') order by batchNum";
		List<WorkOrder> workOrders = workOrderDao.query(sql);
		return workOrders;
	}
	/**
	 * 
	 * @param id
	 * @return
	 */
	public WorkOrder loadWorkOrder(Integer id){
		return workOrderDao.findById(id);
	}
	/**
	 * 查询所有已经完成但还没有入库的工作单
	 * @param part
	 * @return
	 */
	public List<WorkOrder> listCompletedPOItems(GenericPart part){
		String query = "from WorkOrder where (status = 'INSPECTED' or status = 'REPORTED' )";
		if(null != part){
			if(null != part.getPartCode() && !"".equals(part.getPartCode())){
				query += " and partCode = '"+part.getPartCode()+"'";
			}
		}
		String group = " group by productionOrderItem.itemId,batchNum,partCode ";
		String order = "";
		List<WorkOrder> orders = workOrderDao.query(query+group+order);
		return orders;
	}
	/**
	 * 
	 * @param wo
	 * @return
	 */
	public List<WorkOrder> queryWorkOrderByBatchNum(WorkOrder wo){
		String query = "from WorkOrder where quantity > 0 and batchNum='"+wo.getBatchNum()+"' and sequence >= "+wo.getSequence();
		String group = " ";
		String order = "order by id,sequence";
		List<WorkOrder> orders = workOrderDao.query(query+group+order);
		return orders;
	}
	
	
}
